<?php

namespace app\apiadmin\service\statics;

use app\apiadmin\controller\liveManager\LiveStatus;
use app\apiadmin\service\data\RedisService;
use DateTime;
use MongoDB\BSON\UTCDateTime;
use think\facade\Db;
use think\facade\Log;

/**
 *
 * 记录直播数据 记录某一次直播中用户相关的数据
 *
 * 1 从直播开始计算,
 *      用户进入直播间
 *      用户离开直播间
 */
class LiveUserStaticsService
{
    /** @var MongoDbService */
    private $live_user_mongodb;

    /** @var MongoDbService */
    private $live_user_msg_mongodb;

    /** @var MongoDbService */
    private $liveId;

    public function __construct($liveId)
    {
        $this->liveId = $liveId;
        $this->live_user_mongodb = MongoDBService::getInstance("live_user_" . $liveId);
        $this->live_user_msg_mongodb = MongoDBService::getInstance("live_user_msg_" . $liveId);
    }

    public function OnLiveUserEnter($userId, $params)
    {
        $docWhere = ["live_user_id" => $userId];
        $colletcion = $this->live_user_mongodb->getCollection();
        //
        // 当前进用户从消息系统进入到 直播间中 产生一下的数据
        $newUserEnterInfo = [
            "online_status" => 1, // 在线状态
            "last_enter_time" => new UTCDateTime($params["EventTime"]),
            "online_time" => 0, // 在线时长
            "live_user_id" => $userId,

        ];

        //j进入直播间history 记录 时间 状态
        $enter_log_item = [
            "event_time" => new UTCDateTime($params["EventTime"]),
            "status" => 1,
            "create_time" => new UTCDateTime(microtime(true) * 1000),
        ];

        $oldDoc = $colletcion->findOne($docWhere);
        if (empty($oldDoc)) {
            // 无异常数据 没有先收到 离开信息
            $newUserEnterInfo["exit_first"] = 0;
            // 不存在 补充用户信息
            $userInfo = self::getUserInfo($userId);

            $newUserEnterInfo["del"] = 0;

            // 合并数据,合并用户信息
            $newDoc = array_merge($newUserEnterInfo, $userInfo);
            $newDoc["enter_log"][] = $enter_log_item;

            $colletcion->insertOne($newDoc);
        } else {

            // 获取进入进出日志
            $enter_log = $oldDoc["enter_log"];
            unset($newUserEnterInfo["online_time"]);

            $colletcion->updateOne($docWhere, [
                "\$set" => [
                    "online_status" => 1, // 在线状态
                    "last_enter_time" => new UTCDateTime($params["EventTime"]),
                ],
                "\$push" => [
                    "enter_log" => $enter_log_item,
                ],
            ]);
        }
    }

    public function OnLiveUserExit($userId, $params)
    {
        $params = json_decode($params, true);
        $docWhere = ["live_user_id" => $userId];
        $colletcion = $this->live_user_mongodb->getCollection();
        //
        // 当前进用户从消息系统进入到 直播间中 产生一下的数据
        $newUserEnterInfo = [
            "online_status" => 0, // 在线状态 0 离开
            "last_exit_time" => new UTCDateTime($params["EventTime"]),
            "live_user_id" => $userId,

        ];
        //j进入直播间history 记录 时间 状态
        $enter_log_item = [
            "event_time" => new UTCDateTime($params["EventTime"]),
            "status" => 0,
            "create_time" => new UTCDateTime(microtime(true) * 1000),
        ];
        $oldDoc = $colletcion->findOne($docWhere);
        if (empty($oldDoc)) {
            // 有异常信息 离开在 进入之前
            $newUserEnterInfo["exit_first"] = 1;
            // 不存在 补充用户信息
            $userInfo = self::getUserInfo($userId);
            // 合并数据,合并用户信息
            $newDoc = array_merge($newUserEnterInfo, $userInfo);
            $newDoc["enter_log"][] = $enter_log_item;
            $colletcion->insertOne($newDoc);
        } else {
            // 获取进入进出日志
            $enter_log = $oldDoc["enter_log"];
            // 获取最后一条离开的记录
            /** @var UTCDateTime */
            $last_enter_time = null;

            foreach ($enter_log as $key => $value) {
                if ($value["status"] == 1) {
                    $last_enter_time = $value["event_time"];
                }
            }
            if (!empty($last_enter_time) && !empty($params["EventTime"])) {
                $time_diff = (new UTCDateTime($params["EventTime"]))->toDateTime()->getTimestamp() - $last_enter_time->toDateTime()->getTimestamp();
            } else {
                $time_diff = 0;
            }

            $time_diff = $time_diff + $oldDoc["online_time"];

            //记录直播观看总时长
            $liveStatus = new LiveStatus($this->liveId);
            $liveStatus->set_zong_guankan_shichang($time_diff);

            //获取直播观看总时长
            $zongshicahng = $liveStatus->get_zong_guankan_shichang();

            //获取总人数
            $zongrenshu = $liveStatus->get_guankan_renshu();

            //记录平均观看时长
            if ($zongrenshu) {
                $liveStatus->set_pingjun_guankan_shichang(number_format($zongshicahng / $zongrenshu, 2));
            } else {
                $liveStatus->set_pingjun_guankan_shichang(0);
            }
            $colletcion->updateOne($docWhere, [
                "\$set" => [
                    "online_status" => 0,
                    "last_exit_time" => new UTCDateTime($params["EventTime"]),
                ],
                "\$push" => [
                    "enter_log" => $enter_log_item,
                ],
                "\$inc" => [
                    "online_time" => $time_diff,
                ],
            ]);

        }
    }

    public static function getUserInfo($userId)
    {
        if (str_starts_with($userId, "A_" . env("Live.live_pre"))) {
            $userId = str_replace("A_" . env("Live.live_pre"), "", $userId);
            $admin_info = Db::name("siyu_sys_member")
                ->where("uid", $userId)
                ->field("uid as id , nick_name as nickname,phone,face as wx_avatarurl")
                ->find();
            $admin_info["type"] = "a";
            return $admin_info;

        } else if (str_starts_with($userId, "R_" . env("Live.live_pre"))) {
            $userId = str_replace("R_" . env("Live.live_pre"), "", $userId);
            $robot_info = Db::name("siyu_shuziren_list")
                ->where("id", $userId)
                ->field(" id , nick as nickname , touxiang_img as wx_avatarurl")
                ->find();
            $robot_info["phone"] = "";
            $robot_info["type"] = "r";
            return $robot_info;

        } else if (str_starts_with($userId, "M_" . env("Live.live_pre"))) {
            $userId = str_replace("M_" . env("Live.live_pre"), "", $userId);
            $admin_info = Db::name("siyu_sys_member")
                ->where("uid", $userId)
                ->field("uid as id , nick_name as nickname,phone,face as wx_avatarurl")
                ->find();
            $admin_info["type"] = "m";
            return $admin_info;

        } else if (str_starts_with($userId, env("Live.live_pre"))) {

            $userId = str_replace(env("Live.live_pre"), "", $userId);
            $userInfo = Db::name("siyu_user")
                ->where("id", $userId)
                ->field(" id , nickname,phone,wx_avatarurl,unionid as wx_unionid")
                ->find();

            $userInfo["type"] = "u";
            return $userInfo;

        } else {

            // 不存在 补充用户信息
            $userInfo = Db::name("siyu_user")
                ->where("id", $userId)
                ->field(" id , nickname,phone,wx_avatarurl,unionid as wx_unionid")
                ->find();

            $userInfo["type"] = "u";
            return $userInfo;

        }

    }

    public function OnLiveUserSendMsg($userId, $params)
    {
        Log::channel("imInfo")->info("ImCallback:OnLiveUserSendMsg:---" . $userId . '---' . json_encode($params));

        // 用户评论记录
        $docWhere = ["live_user_id" => $userId];
        $colletcion = $this->live_user_msg_mongodb->getCollection();

        Log::channel("imInfo")->info("ImCallback:OnLiveUserSendMsg0:---");

        $CloudCustomData = $params["CloudCustomData"];
        $customTag = null;
        // CloudCustomData 自定数据判断是否是数字人
        if ($CloudCustomData !== "") {
            $customTag = json_decode($CloudCustomData, true);
        }

        Log::channel("imInfo")->info("ImCallback:OnLiveUserSendMsg1:---");

        // 消息发送时间
        $MsgTime = $params["MsgTime"] ?? 0;
        $MsgSeq = $params["MsgSeq"] ?? 0;
        $cloud = json_decode($params["CloudCustomData"], true);
        $content = "";
        $msgBody = $params["MsgBody"];
        if ($msgBody[0]["MsgType"] == "TIMTextElem") {
            $content = $msgBody[0]["MsgContent"]["Text"];
        }

        Log::channel("imInfo")->info("ImCallback:OnLiveUserSendMsg2:---");

        //计算发送时间
        $service_start_time = RedisService::getLiveStartTime($this->liveId); //发送时间   相对于开播时间
        $sendtime = gmdate("H:i:s", time() - $service_start_time);
        Log::channel("imInfo")->info("ImCallback:sendtime:-----" . $sendtime);
        // $sendtime2 =date('Y-m-d H:i:s',strtotime(date('Y-m-d').' '.$sendtime)-8*60*60);
        // Log::channel("imInfo")->info("ImCallback:sendtime2:-----".$sendtime2);
        // $dateTime = new DateTime($sendtime2);
        // $iso8601String = $dateTime->format('Y-m-d\TH:i:s.\Z'); // 保留微秒部分，但后面会截断
        // $iso8601String = rtrim(substr($iso8601String, 0, -1), '0') . '000Z'; // 截取到秒后的微秒部分，并填充或截断到三位数

        // Log::channel("imInfo")->info("ImCallback:iso8601String:-----".$iso8601String);
        $msg = [
            "live_user_id" => $userId, // 用户 id
            "msg_send_time" => $MsgTime, // 消息发送时间
            "msg_seq" => $MsgSeq, // 消息序号
            "cloud_custom_data" => $params["CloudCustomData"],
            "no" => $cloud['no'],
            "content" => $content, // 消息内容
            "create_time" => new UTCDateTime(microtime(true) * 1000), // 消息创建时间
            "msg_type" => $msgBody[0]["MsgType"], // 消息类型
            "del" => 0,
            "is_new_msg" => true, //本场新评论
            "content_state" => 1,
            "send_time" => new UTCDateTime(microtime(true) * 1000), //编辑时控件显示
            "send_time2" => $sendtime, //列表显示
        ];

        Log::channel("imInfo")->info("ImCallback:msg2:-----" . json_encode($msg));

        $userInfo = $this->getUserInfo($userId);
        //Log::channel("imInfo")->info("ImCallback:userInfo:-----" . json_encode($userInfo));
        if (empty($userInfo)) {
            $msg["user_type"] = "unknown";
        } else {
            $msg["user_type"] = $userInfo["type"];
            $msg["nickname"] = $userInfo["nickname"];
            $msg["phone"] = $userInfo["phone"];

            $msg["wx_unionid"] = "";
            $msg["wx_avatarurl"] = $userInfo["wx_avatarurl"];
        }
        Log::channel("imInfo")->info("ImCallback:msg3:-----" . json_encode($msg));
        // 从 customTag 中获取 is_robot_msg 复播标识 只有从数字人或者评论人发过来的消息才有这个字段
        if (empty($customTag)) {
            $msg["is_real_msg"] = true;
        } else {
            // 这里判断
            if (isset($customTag["is_robot_msg"]) && $customTag["is_robot_msg"] == 1) {
                $msg["is_real_msg"] = false;
                $msg["is_new_msg"] = false;
            } else {
                $msg["is_real_msg"] = true;
                $msg["is_new_msg"] = true;

            }

        }
        Log::channel("imInfo")->info("ImCallback:msg:-----" . json_encode($msg));
        $ret = $colletcion->insertOne($msg);

    }
    // 检查某个用户在某场直播是不是看过
    public function Checkiflook($liveId, $userid, $push_file_name)
    {
        // $docWhere = ["del" => 0];
        $res = false;
        for ($i = 1; $i <= $liveId; $i++) {
            $mongodb_model = MongoDBService::getInstance("live_user_" . $i);
            $docWhere = ["live_user_id" => (string) $userid];
            $colletcion = $mongodb_model->getCollection();

            $oldDoc = $colletcion->findOne($docWhere);
            if ($oldDoc) {
                $liveinfo = DB::table('xh_siyu_live_manager')->where('id=' . $i)->find();
                if (empty($liveinfo)) {continue;}
                if ($liveinfo['push_file_name'] == $push_file_name) {
                    $res = true;
                }
            }
        }

        return $res;
    }

}
